// 对象转换成查询字符串方法
function queryStringify(obj) {
    let str = ''
  
    for (let k in obj) {
      str += k + '=' + obj[k] + '&'
    }
  
    return str.slice(0, -1)
  }
  
  // 封装 ajax 的代码
  function ajax(options = {}) {
    // 0. 从 options 内拿到所有的信息, 为了后面验证的时候使用方便
    const { url, method, async, data, headers, dataType, success } = options
  
    // 1. 验证 options 内的信息
    // 1-1. 验证 options 内的 url 信息是否填写了
    if (!url) throw new Error('url 为必填选项, 请传递此项内容, ^_^')
  
    // 1-2. 验证 method 信息
    if (!(method === undefined || /^(get|post)$/i.test(method))) throw new Error('method 目前只接受 "GET" 或者 "POST" 方式, 请期待更新 (#^.^#)')
  
    // 1-3. 验证 async 信息
    if (!(async === undefined || typeof async === 'boolean')) throw new Error('async 需要传递一个 "Boolean" 类型数据呦 O(∩_∩)O哈哈~')
  
    // 1-4. 验证 data 信息
    if (!(data === undefined || typeof data === 'string' || Object.prototype.toString.call(data) === '[object Object]'))  throw new Error('data 需要传递一个 "String" 或者 "Object" 类型数据 o(*￣︶￣*)o')
  
    // 1-5. 验证 headers 信息
    if (!(headers === undefined || Object.prototype.toString.call(headers) === '[object Object]')) throw new Error('headers 需要传递一个 "Object" 类型数据 o(*￣︶￣*)o')
  
    // 1-6. 验证 dataType 信息
    if (!(dataType === undefined || /^(json|string)$/i.test(dataType))) throw new Error('dataType 目前只接受 "json" 或者 "string" 两种值')
  
    // 1-7. 验证 success 信息
    if (!(success === undefined || typeof success === 'function')) throw new Error('success 需要传递一个 "Function" 类型数据')
  
    // 2. 准备一套默认值
    const _default = {
      url: url,
      method: method || 'GET',
      async: async ?? true,
      data: data || '',
      headers: { 'content-type': 'application/x-www-form-urlencoded', ...headers },
      dataType: dataType || 'string',
      success: success || function () {}
    }
    // 2-1. 调整一下 data 的值
    if (typeof _default.data === 'object') _default.data = queryStringify(_default.data)
    // 2-2. 调整一下 url 的值
    if (/^get$/i.test(_default.method) && _default.data) _default.url += '?' + _default.data
  
    // 3. 发送请求的代码
    const xhr = new XMLHttpRequest()
  
    xhr.open(_default.method, _default.url, _default.async)
  
    xhr.onload = function () {
      // 暂时直接打印结果
      const res = _default.dataType === 'string' ? xhr.responseText : JSON.parse(xhr.responseText)
  
      // 调用 _default.success 函数
      _default.success(res)
    }
  
    // 只要 headers 内有内容, 就设置到请求头上
    for (let k in _default.headers) xhr.setRequestHeader(k, _default.headers[k])
  
    // 分辨一下, 是 get 还是 post 请求
    ;/^get$/i.test(_default.method) ? xhr.send() : xhr.send(_default.data)
  }
  
  // 使用 Promise 语法, 对 ajax 进行二次封装
  function pAjax(options = {}) {
    return new Promise((resolve, reject) => {
      ajax({
        url: options.url,
        data: options.data,
        async: options.async,
        method: options.method,
        headers: options.headers,
        dataType: options.dataType,
        success (res) {
          resolve(res)
        }
      })
    })
  }

  const 